package com.spring.poi.tl.config;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.util.StrUtil;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.PictureType;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.data.style.PictureStyle;
import com.deepoove.poi.policy.AbstractRenderPolicy;
import com.deepoove.poi.render.RenderContext;
import com.deepoove.poi.xwpf.NiceXWPFDocument;
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.Section;
import com.spire.doc.documents.Paragraph;
import com.spire.doc.fields.DocPicture;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ooxml.POIXMLTypeLoader;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.openxml4j.opc.*;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import org.xml.sax.InputSource;

import java.io.*;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @author liuzhiqiang
 */
public class VideoRenderPolicy extends AbstractRenderPolicy<File> {

    private static final String ICON = "";

    private static final String SHAPE_TYPE_ID = "_x0000_t80";

    private static final String contentType = "application/vnd.openxmlformats-officedocument.oleObject";

    private static final String SHAPE_TYPE_XML = "<v:shapetype id=\"" + SHAPE_TYPE_ID + "\" coordsize=\"21600,21600\" o:spt=\"75\" o:preferrelative=\"t\" "
            + "                      path=\"m@4@5l@4@11@9@11@9@5xe\" filled=\"f\" stroked=\"f\">\n"
            + "                        <v:stroke joinstyle=\"miter\"/>\n"
            + "                        <v:formulas>\n"
            + "                            <v:f eqn=\"if lineDrawn pixelLineWidth 0\"/>\n"
            + "                            <v:f eqn=\"sum @0 1 0\"/>\n"
            + "                            <v:f eqn=\"sum 0 0 @1\"/>\n"
            + "                            <v:f eqn=\"prod @2 1 2\"/>\n"
            + "                            <v:f eqn=\"prod @3 21600 pixelWidth\"/>\n"
            + "                            <v:f eqn=\"prod @3 21600 pixelHeight\"/>\n"
            + "                            <v:f eqn=\"sum @0 0 1\"/>\n"
            + "                            <v:f eqn=\"prod @6 1 2\"/>\n"
            + "                            <v:f eqn=\"prod @7 21600 pixelWidth\"/>\n"
            + "                            <v:f eqn=\"sum @8 21600 0\"/>\n"
            + "                            <v:f eqn=\"prod @7 21600 pixelHeight\"/>\n"
            + "                            <v:f eqn=\"sum @10 21600 0\"/>\n"
            + "                        </v:formulas>\n"
            + "                        <v:path o:extrusionok=\"f\" gradientshapeok=\"t\" o:connecttype=\"rect\"/>\n"
            + "                        <o:lock v:ext=\"edit\" aspectratio=\"t\"/>\n"
            + "                    </v:shapetype>\n";

    @Override
    protected boolean validate(File data) {
        return null != data && null != data;
    }

    @Override
    protected void afterRender(RenderContext<File> context) {
        super.clearPlaceholder(context, false);
    }

    @Override
    public void doRender(RenderContext<File> context) throws Exception {
        NiceXWPFDocument doc = context.getXWPFDocument();
        XWPFRun run = context.getRun();
        CTR ctr = run.getCTR();

        String uuidRandom = UUID.randomUUID().toString().replace("-", "") + ThreadLocalRandom.current().nextInt(1024);
        String shapeId = "_x0000_i21" + uuidRandom;
        String part = "/word/embeddings/oleObject1.bin";
        PictureRenderData icon = Pictures.ofBase64(ICON, PictureType.PNG)
                .size(100, 64)
                .create();
        byte[] image = icon.readPictureData();
        PictureType pictureType = icon.getPictureType();
        if (null == pictureType) {
            pictureType = PictureType.suggestFileType(image);
        }

        PictureStyle style = icon.getPictureStyle();
        if (null == style) {
            style = new PictureStyle();
        }
        double widthPt = Units.pixelToPoints(style.getWidth());
        double heightPt = Units.pixelToPoints(style.getHeight());
        String imageRId = doc.addPictureData(image, pictureType.type());

        FileReader fileReader = new FileReader(context.getData());
        PackagePartName partName = PackagingURIHelper.createPartName(part);


        Document doc2 = new Document();
        Section section = doc2.addSection();
        Paragraph para3 = section.addParagraph();
        DocPicture picture = new DocPicture(doc2);
        picture.loadImage(image);
        para3.appendOleObject(fileReader.readBytes(),picture, "mp4");
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        doc2.saveToStream(byteArrayOutputStream, FileFormat.Docx);

        ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
        for (POIXMLDocumentPart relation : new XWPFDocument(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())).getRelations()) {
            if (StrUtil.equals(relation.getPackagePart().getContentType(), "application/vnd.openxmlformats-officedocument.oleObject")) {
                IoUtil.copy(relation.getPackagePart().getInputStream(), arrayOutputStream);
            }
        }
        PackagePart packagePart = doc.getPackage().createPart(partName,contentType);
        try (OutputStream out = packagePart.getOutputStream()) {
            out.write(arrayOutputStream.toByteArray());
        } catch (IOException e) {
            throw new POIXMLException(e);
        }


        PackageRelationship ole = doc.getPackagePart().addRelationship(partName, TargetMode.INTERNAL,
                POIXMLDocument.PACK_OBJECT_REL_TYPE);
        String oleId = ole.getId();
        String wObjectXml = "<w:object xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\""
                + "             xmlns:v=\"urn:schemas-microsoft-com:vml\""
                + "             xmlns:o=\"urn:schemas-microsoft-com:office:office\""
                + "             xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\""
                + "             w:dxaOrig=\"1520\" w:dyaOrig=\"960\">\n" + SHAPE_TYPE_XML
                + "                    <v:shape id=\"" + shapeId + "\" type=\"#"
                + SHAPE_TYPE_ID + "\" alt=\"\" style=\"width:" + widthPt + "pt;height:" + heightPt
                + "pt;mso-width-percent:0;mso-height-percent:0;mso-width-percent:0;mso-height-percent:0\" o:ole=\"\">\n"
                + "                        <v:imagedata r:id=\"" + imageRId + "\" o:title=\"\"/>\n"
                + "                    </v:shape>\n"
                + "                    <o:OLEObject Type=\"Embed\" ProgID=\"Package\" ShapeID=\"" + shapeId
                + "\" DrawAspect=\"Icon\" ObjectID=\""+shapeId+"\" r:id=\""+ oleId + "\">\n"
                + "                     <o:FieldCodes>\\s</o:FieldCodes>\n"
                + "                    </o:OLEObject>"
                + "            </w:object>";

        org.w3c.dom.Document document2 = DocumentHelper.readDocument(new InputSource(new StringReader(wObjectXml)));
        ctr.set(XmlObject.Factory.parse(document2.getDocumentElement(), POIXMLTypeLoader.DEFAULT_XML_OPTIONS));
    }
}
